package org.wu.framework.easy.markdown.processor;

import org.wu.framework.easy.markdown.endpoint.EasyMarkDownFieldPoint;
import org.wu.framework.easy.markdown.endpoint.EasyMarkDownPoint;
import org.wu.framework.easy.markdown.stereotype.markdown.EasyMarkDown;
import org.wu.framework.easy.markdown.stereotype.markdown.EasyMarkDownField;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.wu.framework.core.ReflexUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 处理Java 对象导出markdown
 */
public class JavaBeanEasyMarkDownProcessor extends AbstractEasyMarkDownProcessor implements EasyMarkDownProcessor {


    /**
     * 是否支持excel 处理
     *
     * @param markdownBeanList markdown 对象
     * @return boolean
     */
    @Override
    public boolean support(Object markdownBeanList) {
        return markdownBeanList != null;
    }

    /**
     * 获取 markdown结构信息
     *
     * @param markDownBean markdown对象（集合或者单个）
     * @return markdown结构信息
     */
    @Override
    public EasyMarkDownPoint findEasyMarkDownPoint(Object markDownBean) {


        EasyMarkDownPoint easyMarkDownPoint = new EasyMarkDownPoint();


        Class<?> markdownFirstBeanClass = markDownBean.getClass();

        EasyMarkDown easyMarkDown = AnnotatedElementUtils.findMergedAnnotation(markdownFirstBeanClass, EasyMarkDown.class);
        if (easyMarkDown != null) {
            String fileName = easyMarkDown.fileName();
            String suffix = easyMarkDown.suffix();
            easyMarkDownPoint.setFileName(fileName);
            easyMarkDownPoint.setSuffix(suffix);
        }
        List<EasyMarkDownFieldPoint> easyMarkDownFieldPointList = findEasyMarkDownFieldPointList(markDownBean);

        easyMarkDownPoint.setMarkDownFieldPointList(easyMarkDownFieldPointList);
        return easyMarkDownPoint;
    }

    /**
     * 解析对象 中字段注解
     *
     * @param markdownFirstBean 对象
     * @return List<EasyMarkDownFieldPoint>
     */
    private List<EasyMarkDownFieldPoint> findEasyMarkDownFieldPointList(Object markdownFirstBean) {
        Class<?> markdownFirstBeanClass = markdownFirstBean instanceof Class<?> ? (Class<?>) markdownFirstBean : markdownFirstBean.getClass();
        List<EasyMarkDownFieldPoint> easyMarkDownFieldPointList = new ArrayList<>();

        if (Map.class.isAssignableFrom(markdownFirstBeanClass)) {
            // TODO


        } else {
            for (Field declaredField : markdownFirstBeanClass.getDeclaredFields()) {
                EasyMarkDownFieldPoint easyMarkDownFieldPoint = new EasyMarkDownFieldPoint();
                easyMarkDownFieldPoint.setField(declaredField);

                String name = declaredField.getName();
                boolean basicDataType = true;
                EasyMarkDownField easyMarkDownField = AnnotatedElementUtils.findMergedAnnotation(declaredField, EasyMarkDownField.class);

                if (easyMarkDownField != null) {
                    name = easyMarkDownField.name();
                    basicDataType = easyMarkDownField.isBasicDataType();
                    if (!basicDataType) {
                        // 非基本数据类型
                        List<EasyMarkDownFieldPoint> markDownFieldPointList = findEasyMarkDownFieldPointList(declaredField.getClass());
                        if (Map.class.isAssignableFrom(declaredField.getType())) {
                            easyMarkDownFieldPoint.setMapFiled(true);
                        } else if (Collection.class.isAssignableFrom(declaredField.getType())) {
                            easyMarkDownFieldPoint.setCollectionFiled(true);
                        }
                        easyMarkDownFieldPoint.setMarkDownBeanFiledPointList(markDownFieldPointList);
                    }
                } else {

                }
                easyMarkDownFieldPoint.setName(name);
                easyMarkDownFieldPoint.setBasicDataType(basicDataType);

                easyMarkDownFieldPointList.add(easyMarkDownFieldPoint);
            }
        }

        return easyMarkDownFieldPointList;
    }


    /**
     * Get the order value of this object.
     * <p>Higher values are interpreted as lower priority. As a consequence,
     * the object with the lowest value has the highest priority (somewhat
     * analogous to Servlet {@code load-on-startup} values).
     * <p>Same order values will result in arbitrary sort positions for the
     * affected objects.
     *
     * @return the order value
     * @see #HIGHEST_PRECEDENCE
     * @see #LOWEST_PRECEDENCE
     */
    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 获取对象中的某个字段
     *
     * @param easyMarkDownFieldPoint 字段数据结构
     * @param markdownBean           对象
     * @return 返回 bean中字段数据
     */
    @Override
    Object invokeFieldValue(EasyMarkDownFieldPoint easyMarkDownFieldPoint, Object markdownBean) {
        return ReflexUtils.findDeclaredFieldBean(markdownBean, easyMarkDownFieldPoint.getField());
    }

    /**
     * 如果返回的字段是一个List或者返回对象中某个字段是List 那么递归获取对象中第一个集合的长度和
     *
     * @param easyMarkDownFieldPoint 字段数据结构
     * @param markdownBean           对象
     * @return 获取对象中第一个集合的长度和
     */
    @Override
    int sumFieldListLength(EasyMarkDownFieldPoint easyMarkDownFieldPoint, Object markdownBean) {
        Object invokeFieldValue = invokeFieldValue(easyMarkDownFieldPoint, markdownBean);
        if (easyMarkDownFieldPoint.isBeanFiled()) {
            if (hasCollection(easyMarkDownFieldPoint)) {

            }
            return 0;
        } else if (easyMarkDownFieldPoint.isCollectionFiled()) {

            return 1;
        } else {
            return 1;
        }

    }
}
